/*
 *   Copyright 2008 Marcos Silva Pereira
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
import org.dbunit.dataset.IDataSet
import org.dbunit.dataset.CompositeDataSet
import org.dbunit.dataset.xml.FlatXmlDataSet
import org.dbunit.database.IDatabaseConnection
import org.dbunit.database.DatabaseConnection
import org.dbunit.operation.DatabaseOperation

import org.codehaus.groovy.grails.commons.GrailsClassUtils
import org.apache.commons.logging.Log
import org.apache.commons.logging.LogFactory

import java.sql.Connection

class DataSetInfo {

    private static final Log log = LogFactory.getLog(DataSetInfo.class)

    String className
    List datasets

    File datasetHomeDirectory

    static info() {
        new DataSetInfo()
    }

    DataSetInfo forClass(Class c) {

        this.datasets = GrailsClassUtils.getStaticPropertyValue(c, 'datasets')
        this.className = c.name
        this.datasetHomeDirectory = new File("test/datasets")

        return this
    }

    DataSetInfo withDataSetHome(dir) {
        if(!dir) {
            throw new IllegalArgumentException("Invalid home directory for datasets")
        }
        this.datasetHomeDirectory = new File(dir.toString())
        return this
    }

    CompositeDataSet getDataset() {
    	def datasets = this.allDatasetFiles?.collect { file ->
            log.info "Loading dataset file $file"
            new FlatXmlDataSet(file)
        }
        return new CompositeDataSet(datasets as IDataSet[])
    }

    // TODO logs to warn about dataset not found
    List getAllDatasetFiles() {

        def files = []

        FilenameFilter filter = new DatasetFilenameFilter()

        this.datasets?.collect { ds -> list(datasetHomeDirectory, ds, filter) }
                      .each { list -> files.addAll(list?.sort { it }) }

        return files
    }

    void load(Connection connection) {
        try {

            IDatabaseConnection conn = new DatabaseConnection(connection)
            DatabaseOperation.CLEAN_INSERT.execute conn, this.dataset

            log.info "Loading datasets for test $className"

        } catch(Exception ex) {
            log.error "Could not load datasets for test $className", ex
        }
    }

    void unload(Connection connection) {
        try {

            IDatabaseConnection conn = new DatabaseConnection(connection)
            DatabaseOperation.DELETE.execute conn, this.dataset

            log.info "Deleting datasets for test $className"

        } catch(Exception ex) {
            log.error "Could not delete datasets for test $className", ex
        }
    }

    private List list(home, dataset, filter) {

        File datasetHome = new File(home, dataset)

        log.info "List all datasets from $datasetHome"

        def list = datasetHome.listFiles(filter) as List
        list ?: []
    }
}